<?php
/**
 * @version      BOSSCMS-Free
 * @trademark    BOSSCMS
 * @copyright    Copyright © by BOSSCMS-Free (https://www.bosscms.net/) 保留所有权利
 * @license      https://gitee.com/Greenpeas/BOSSCMS/license/ 和 https://www.bosscms.net/freelicense/
 * @link         https://www.bosscms.net/
 * @author       温州软界网络技术有限公司
**/
defined('IS_OK') or exit('Access Forbidden');

class rewrite
{
	public static function rule()
	{
		global $G;
		$G['config'] = arrOption(mysql::select_all('name,value','config',"name LIKE 'rule%' AND parent='0' AND type='0' AND lang='0'"));
		$G['language'] = mysql::select_one('*','language',"defaults='1'");
		$rule = false;
		$ruleall = self::json();
		if($G['path']['quest']){
			parse_str($G['path']['quest'],$get);
			$G['get'] = strFilter($get);
		}
		foreach($ruleall as $k=>$v){
			$G['rp'] = array();
			$reg = preg_replace_callback(
				'/\[\w+\]/',
				function($match){
					if($match[0]){
						$m = preg_replace('/^\[|\]$/','',$match[0]);
						global $G;
						static $i;
						$i++;
						$G['rp'][$m] = $i;
						if($m=='folder'){
							if(isset($G['rule_all']['folder'])){
								return $G['rule_all']['folder'];
							}else{
								$res = mysql::select_all('folder','items',"type!=9 AND display=1 AND lang=lang");
								$folder = array();
								foreach($res as $v){
									$folder[] = preg_quote($v['folder']);
								}
								if($folder){
									usort($folder,function($a,$b){
										if(strlen($a)==strlen($b)) return 0;
										return strlen($a)>strlen($b)?-1:1;
									});
									return $G['rule_all']['folder']='('.implode('|',$folder).')';
								}else{
									return $G['rule_all']['folder']='';
								}
							}
						}else if(preg_match('/^(static|tag)$/',$m)){
							return '([a-zA-Z0-9_^\x00-\xff]+?)';
						}else if(preg_match('/^(lang|type)$/',$m)){
							return '([a-zA-Z0-9]+?)';
						}else if(preg_match('/^(items|id|pages)$/',$m)){
							return '([0-9]+?)';
						}else{
							return '(.+?)';
						}
					}
				},
				regFilter($v,'[]')
			);
			preg_match('/^'.$reg.'$/',$G['path']['resource'],$match);
			if($match[0]){
				$m = strFilter($match);
				$r = 'rule'.substr($k,0,1);
				if(method_exists('rewrite', $r)){
					if($rule = call_user_func(array('rewrite',$r), $m, $G['rp'])){
						break;
					}
				}
			}
		}
		unset($G['rule_all']);
		unset($G['rp']);
		if(mysql::total('config',"name='rewrite_open' AND value='1' AND parent='0' AND type='0' AND lang='{$G['get']['lang']}'")){
			return $rule;
		}
	}
	
	public static function json()
	{
		global $G;
		if(is_file(ROOT_PATH.'cache/rule.json')){
			$ruleall = json::get(ROOT_PATH.'cache/rule.json');
		}else{
			$ruleall = array();
			if($G['config']['rule']){
				$rules = json::decode($G['config']['rule']);
			}else{
				into::basic_json('rule');
				$rules = json::decode($G['rule']);
			}
			foreach($rules as $k=>$v){
				if($k==2){
					if(strstr($v,'[folder]')){
						if(preg_match('/[a-zA-Z]/',str_replace('[pages]','','-page[pages]'))){
							$ruleall[$k.'3'] = preg_replace('/[^\/]+$/','',$v). preg_replace('/^[^\w\[]+/','','-page[pages]').'.html';
						}
					}else{
						$ruleall[$k.'3'] = $v. '-page[pages].html';
					}
				}
				if(preg_match('/^(2|4|6|7)$/',$k)){
					$ruleall[$k.'2'] = $v.'-[lang]-page[pages].html';
					$ruleall[$k.'1'] = $v.'-page[pages].html';
				}
				$ruleall[$k.'0'] = $v.'-[lang].html';
				$ruleall[$k] = $v.($k==6?'':'.html');
			}
			json::put(ROOT_PATH.'cache/rule.json',$ruleall);
		}
		return $ruleall;
	}
	
	
	public static function rule1($m, $rp)
	{
		global $G;
		$lang = $m[$rp['lang']];
		if($lang = self::lang($lang)){
			$G['get']['lang'] = $lang;
			$G['path']['home'] = true;
			$G['path']['folder'] = '';
			return true;
		}
	}	
	public static function rule2($m, $rp)
	{
		global $G;
		$folder = $m[$rp['folder']];
		$items = $m[$rp['items']];
		$lang = $m[$rp['lang']];
		$pages = $m[$rp['pages']];
		if($lang = self::lang($lang)){
			if(($folder && $res=mysql::select_one('id,type,folder','items',"folder='{$folder}' AND lang='{$lang}'"))|| 
			   ($items && $res=mysql::select_one('id,type,folder','items',"id='{$items}' AND lang='{$lang}'"))){
				$G['get']['pages'] = $pages;
				$G['get']['items'] = $items;
				$G['get']['lang'] = $lang;
				$G['path']['home'] = false;
				$G['path']['folder'] = $res['folder'];
				return true;
			}
		}
	}	
	public static function rule3($m, $rp)
	{
		global $G;
		$folder = $m[$rp['folder']];
		$items = $m[$rp['items']];
		$lang = $m[$rp['lang']];
		$pages = $m[$rp['pages']];
		if($lang = self::lang($lang)){
			if(($folder && mysql::total('items',"folder='{$folder}' AND id='{$items}' AND FIND_IN_SET(type,'1,6,7,8,10') AND lang='{$lang}'"))||
			   (!$folder && $items && mysql::total('items',"id='{$items}' AND FIND_IN_SET(type,'1,6,7,8,10') AND lang='{$lang}'"))){
				$G['get']['pages'] = $pages;
				$G['get']['items'] = $items;
				$G['get']['lang'] = $lang;
				$G['path']['home'] = false;
				$G['path']['folder'] = $folder;
				return true;
			}
		}
	}	
	public static function rule4($m, $rp)
	{
		global $G;
		$folder = $m[$rp['folder']];
		$items = $m[$rp['items']];
		$lang = $m[$rp['lang']];
		$pages = $m[$rp['pages']];
		if($lang = self::lang($lang)){
			if(($folder && mysql::total('items',"folder='{$folder}' AND id='{$items}' AND !FIND_IN_SET(type,'1,6,7,8,10') AND lang='{$lang}'"))||
			   (!$folder && $items && mysql::total('items',"id='{$items}' AND !FIND_IN_SET(type,'1,6,7,8,10') AND lang='{$lang}'"))){
				$G['get']['pages'] = $pages;
				$G['get']['items'] = $items;
				$G['get']['lang'] = $lang;
				$G['path']['home'] = false;
				$G['path']['folder'] = $folder;
				return true;
			}
		}
	}	
	public static function rule5($m, $rp)
	{
		global $G;
		$folder = $m[$rp['folder']];
		$type = $m[$rp['type']];
		$id = $m[$rp['id']];
		$lang = $m[$rp['lang']];
		if($lang = self::lang($lang)){
			if($folder && $res=mysql::select_one('type','items',"folder='{$folder}' AND (FIND_IN_SET(type,'2,3,4,5')) AND lang='{$lang}'")){
				if($id && mysql::total(array_search($res['type'],$G['pass']['type']),"id='{$id}' AND lang='{$lang}'")){
					$G['get']['lang'] = $lang;
					$G['get']['id'] = $id;
					$G['path']['home'] = false;
					$G['path']['folder'] = $folder;
					return true;
				}
			}else if(preg_match('/^\w+$/',$type) && $id && $res=mysql::select_one('items',$type,"id='{$id}' AND lang='{$lang}'")){
				if($res2=mysql::select_one('folder','items',"id='{$res['items']}' AND (FIND_IN_SET(type,'2,3,4,5')) AND lang='{$lang}'")){
					$G['get']['lang'] = $lang;
					$G['get']['id'] = $id;
					$G['path']['home'] = false;
					$G['path']['folder'] = $res2['folder'];
					return true;
				}
			}
		}
	}	
	public static function rule6($m, $rp)
	{
		global $G;
		$folder = $m[$rp['folder']];
		$tag = $m[$rp['tag']];
		$lang = $m[$rp['lang']];
		$pages = $m[$rp['pages']];
		if($lang = self::lang($lang)){
			if($folder && mysql::total('items',"folder='{$folder}' AND (FIND_IN_SET(type,'2,3,4,5')) AND lang='{$lang}'")){
				$G['get']['pages'] = $pages;
				$G['get']['lang'] = $lang;
				$G['get']['tag'] = $tag;
				$G['path']['home'] = false;
				$G['path']['folder'] = $folder;
				return true;
			}
		}
	}	
	public static function rule7($m, $rp)
	{
		global $G;
		$folder = $m[$rp['folder']];
		$static = $m[$rp['static']];
		$lang = $m[$rp['lang']];
		$pages = $m[$rp['pages']];
		if($lang = self::lang($lang)){
			$static = urldecode($static);
			if($res=mysql::select_one('id','items',"folder='{$folder}' AND static='{$static}' AND lang='{$lang}'")){
				$G['get']['pages'] = $pages;
				$G['get']['lang'] = $lang;
				$G['get']['items'] = $res['id'];
				$G['path']['home'] = false;
				$G['path']['folder'] = $folder;
				return true;
			}else if(!$pages && $res=mysql::select_one('type','items',"folder='{$folder}' AND (FIND_IN_SET(type,'2,3,4,5')) AND lang='{$lang}'")){
				if($r=mysql::select_one('id,items',array_search($res['type'],$G['pass']['type']),"static='{$static}' AND lang='{$lang}'")){
					$G['get']['lang'] = $lang;
					$G['get']['id'] = $r['id'];
					$G['get']['items'] = $r['items'];
					$G['path']['home'] = false;
					$G['path']['folder'] = $folder;
					return true;
				}
			}
		}
	}
	
	public static function lang($lang)
	{
		global $G;
		if(!$lang || $G['language']['id']==$lang){
			return $G['language']['id'];
		}else{
			$res = mysql::select_one('id','language',(is_numeric($lang)?"id='{$lang}'":"sign='{$lang}'")."");
			return $res?$res['id']:false;
		}
	}
}
?>